#include <iostream>
#include <memory>
#include <string>
#include <stdio.h>

#include <cctype>
#include <algorithm>

#include "TcpServer.hpp"
#include "Comm.hpp"
#include "Translate.hpp"
#include "Daemon.hpp"

using namespace std;

Translate trans;

void Interact(int sockfd, string &out, const string &in) // 交互
{
    char buffer[1024];
    ssize_t n = read(sockfd, buffer, sizeof(buffer));
    if (n > 0)
    {
        buffer[n] = 0;
        write(sockfd, in.c_str(), in.size());
    }
    else if (n == 0)
    {
        lg.LogMessage(Info, "client quit...\n");
    }
    else
    {
        lg.LogMessage(Error, "listen error, %d : %s\n", errno, strerror(errno));
    }
}

// 未来的服务器是部署在你的云服务器上的，你怎么知道你的服务未来在任何一个时刻，都是健康的呢？？

// 我可以定期(30s)向我的服务器发送最小服务请求，如果得到了回复，说明我们的服务是正常的.
// 这个机制，我们称之为  心跳机制  .我们可以问client->服务器(服务器返回pong表示正常), 反向的 server->client
void Ping(int sockfd, InetAddr addr)
{
    lg.LogMessage(Debug, "%s select %s success,fd : %d\n", addr.PrintDebug().c_str(), "Ping", sockfd);
    string message;
    Interact(sockfd, message, "Pong");
}

void Translate(int sockfd, InetAddr addr)
{
    lg.LogMessage(Debug, "%s select %s success,fd : %d\n", addr.PrintDebug().c_str(), "Translate", sockfd);

    char wordbuff[1024];
    int n = read(sockfd, wordbuff, sizeof(wordbuff) - 1); // 读取到clinet write的消息
    if (n > 0)
        wordbuff[n] = 0;
    string chinese = trans.Excute(wordbuff);

    write(sockfd, chinese.c_str(), chinese.size()); // 把消息写进sockfd中，让client 读取到

    lg.LogMessage(Debug, "%s Translate service,%s -> %s\n", addr.PrintDebug().c_str(), wordbuff, chinese.c_str());
}

void Transform(int sockfd, InetAddr addr)
{
    lg.LogMessage(Debug, "%s select %s success,fd : %d\n", addr.PrintDebug().c_str(), "Transform", sockfd);
    char message[1024];
    int n = read(sockfd, message, sizeof(message));
    if (n > 0)
        message[n] = 0;

    string messagestr = message;
    transform(messagestr.begin(), messagestr.end(), messagestr.begin(), [](unsigned char c)
              { return toupper(c); });

    write(sockfd, messagestr.c_str(), messagestr.size());
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cout << "Usag: \n\t" << argv[0] << " "
             << "local_port\n"
             << endl;
        return Usage_Err;
    }

    uint16_t port = stoi(argv[1]);
    // 将tcpserver设置为守护进程！
    Daemon(false, false);
    // 注意守护进程已经把标准输入输出关闭了，所以需要修改日志把其放到文件中去
    lg.Enable(ClassFile);// 把日志分类型的放到log目录中去

    unique_ptr<TcpServer> tsvr(new TcpServer(port)); // 另外的使用方式
    tsvr->RegisterServer("ping", Ping);
    tsvr->RegisterServer("translate", Translate);
    tsvr->RegisterServer("transform", Transform);
    // unique_ptr<TcpServer> tsvr = make_unique<TcpServer>(port);
    tsvr->Init();
    tsvr->Start(); 

    return 0;
}